/**
 * 认证中间件
 * 处理JWT身份验证和权限检查
 */
const jwt = require('jsonwebtoken');
const config = require('../config');
const logger = require('../utils/logger');

/**
 * 验证JWT令牌
 */
const verifyToken = (req, res, next) => {
  // 从请求头或cookies获取token
  const token = req.headers.authorization?.split(' ')[1] || req.cookies?.token;

  if (!token) {
    return res.status(401).json({ 
      success: false, 
      message: '未提供访问令牌' 
    });
  }

  try {
    // 验证令牌
    const decoded = jwt.verify(token, config.jwt.secret);
    
    // 将用户信息添加到请求对象
    req.user = decoded;
    
    // 记录API访问（可选）
    if (process.env.NODE_ENV === 'development') {
      logger.debug('API访问', { 
        user: decoded.id, 
        role: decoded.role,
        path: req.path,
        method: req.method
      });
    }
    
    next();
  } catch (error) {
    logger.warn('令牌验证失败', { error: error.message });
    
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ 
        success: false, 
        message: '访问令牌已过期' 
      });
    }
    
    return res.status(401).json({ 
      success: false, 
      message: '无效的访问令牌' 
    });
  }
};

/**
 * 验证用户是否为管理员
 */
const isAdmin = (req, res, next) => {
  // 确保先经过verifyToken中间件
  if (!req.user) {
    return res.status(401).json({ 
      success: false, 
      message: '未经身份验证' 
    });
  }
  
  if (req.user.role !== 'admin') {
    logger.security('非管理员尝试访问管理接口', {
      userId: req.user.id,
      role: req.user.role,
      path: req.path
    });
    
    return res.status(403).json({ 
      success: false, 
      message: '权限不足，仅管理员可访问' 
    });
  }
  
  next();
};

/**
 * 验证用户是否有访问特定资源的权限
 */
const hasResourceAccess = (resourceIdField) => {
  return (req, res, next) => {
    // 确保先经过verifyToken中间件
    if (!req.user) {
      return res.status(401).json({ 
        success: false, 
        message: '未经身份验证' 
      });
    }
    
    // 管理员有权访问所有资源
    if (req.user.role === 'admin') {
      return next();
    }
    
    // 获取资源ID
    const resourceId = req.params[resourceIdField];
    
    // 这里应该实现检查用户是否有权访问该特定资源的逻辑
    // 例如，检查资源是否属于该用户
    
    // 临时实现：只允许访问自己的资源
    if (resourceId === req.user.id) {
      return next();
    }
    
    logger.security('用户尝试访问未授权资源', {
      userId: req.user.id,
      resourceId,
      path: req.path
    });
    
    return res.status(403).json({ 
      success: false, 
      message: '权限不足，无法访问此资源' 
    });
  };
};

module.exports = {
  verifyToken,
  isAdmin,
  hasResourceAccess
}; 